﻿using System.IO;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System;
using System.Web;
using System.Web.UI;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.Profile;

namespace Marbles.Core.Web.Templates
{
    public class Page : System.Web.UI.Page
    {

        [Description("Site Map Provider Name")]
        public string SiteMapProvider
        {
            get
            {
                object obj = ViewState["SiteMapProvider"];
                if (obj == null) { return string.Empty; }
                return ((string)obj);
            }
            set { ViewState["SiteMapProvider"] = value; }
        }

        [Description("Set Page Title Seperator Value")]
        public string SiteMapNodeSeparator
        {
            get
            {
                object obj = ViewState["SiteMapNodeSeparator"];
                if (obj == null) { return "::"; }
                return ((string)obj);
            }
            set { ViewState["SiteMapNodeSeparator"] = value; }
        }

        [Description("Set Page title automatically using Site Map")]
        public bool AutoSetPageTitle
        {
            get
            {
                object obj = ViewState["AutoSetPageTitle"];
                if (obj == null) { return true; }
                return ((bool)obj);
            }
            set { ViewState["AutoSetPageTitle"] = value; }
        }

        [Description("Set Internet Explorer Compatiability Mode")]
        public UACompatible UACompatible
        {
            set
            {
                SetUACompatible(value);
            }
        }

        [Description("Set Internet Explorer to Render XP Themed Controls")]
        public bool MSThemeCompatible
        {
            set
            {
                if (value)
                {
                    CreateMeta(string.Empty, "MSThemeCompatible", "yes");
                }
                else
                {
                    CreateMeta(string.Empty, "MSThemeCompatible", "no");
                }
            }
        }

        [Description("Show or Hide Shortcut Icon")]
        public bool ShowShortcutIcon
        {
            get
            {
                object obj = ViewState["ShowShortcutIcon"];
                if (obj == null) { return false; }
                return ((bool)obj);
            }
            set { ViewState["ShowShortcutIcon"] = value; }
        }

        [Description("Set the Page Description")]
        public string Description
        {
            set
            {
                CreateMeta("description", string.Empty, value);
            }
        }

        [Description("Set the Page Author")]
        public string Author
        {
            set
            {
                CreateMeta("author", string.Empty, value);
            }
        }

        [Description("Set the Page Copyright")]
        public string Copyright
        {
            set
            {
                CreateMeta("copyright", string.Empty, value);
            }
        }

        [Description("Set the Page Search Keywords")]
        public string Keywords
        {
            set
            {
                CreateMeta("keywords", string.Empty, value);

            }
        }

        [Description("Set the Page Cache Expiry Date")]
        public DateTime Expires
        {
            set
            {
                SetExpires(value);
            }
        }

        [Description("Set the Page Cache Options")]
        public CacheControl CacheControl
        {
            set
            {
                SetCacheControl(value);
            }
        }

        [Description("Set the Search Robot Options")]
        public Robots[] SearchBot
        {
            set { SetRobots(value, false); }
        }

        [Description("Set the Google Search Robot Options")]
        public Robots[] GoogleBot
        {
            set { SetRobots(value, true); }
        }

        [Description("Get the User Profile")]
        public ProfileBase Profile
        {
            get
            {
                return HttpContext.Current.Profile;
            }
        }

        protected override void OnPreInit(EventArgs e)
        {
            //if (this.Profile != null)
            //{
            //string themename = this.Profile["Theme"].ToString();
            //if (themename != null) { Page.Theme = themename; }
            //}

            base.OnPreInit(e);
        }

        private void SetUACompatible(UACompatible value)
        {
            switch (value)
            {
                case UACompatible.Edge: CreateMeta(string.Empty, "X-UA-Compatible", "IE=Edge"); break;
                case UACompatible.EmulateIE7: CreateMeta(string.Empty, "X-UA-Compatible", "IE=EmulateIE7"); break;
                case UACompatible.EmulateIE8: CreateMeta(string.Empty, "X-UA-Compatible", "IE=EmulateIE8"); break;
                case UACompatible.IE5: CreateMeta(string.Empty, "X-UA-Compatible", "IE=IE5"); break;
                case UACompatible.IE7: CreateMeta(string.Empty, "X-UA-Compatible", "IE=IE7"); break;
                case UACompatible.IE8: CreateMeta(string.Empty, "X-UA-Compatible", "IE=IE8"); break;
            }
        }

        private void SetExpires(DateTime value)
        {
            string datevalue = "0";

            if (value != DateTime.Now)
            {
                datevalue = value.ToString("R");
            }

            CreateMeta(string.Empty, "expires", datevalue);
        }

        private void SetCacheControl(CacheControl CacheControl)
        {
            string value = string.Empty;

            switch (CacheControl)
            {
                case CacheControl.NoCache: value = "no-cache"; break;
                case CacheControl.NoStore: value = "no-store"; break;
                case CacheControl.Private: value = "private"; break;
                case CacheControl.Public: value = "public"; break;
            }

            CreateMeta(string.Empty, "cache-control", value);
            CreateMeta(string.Empty, "pragma", value);
        }

        private void CreateMeta(string name, string httpequiv, string value)
        {
            HtmlMeta meta = new HtmlMeta();
            meta.HttpEquiv = httpequiv;
            meta.Name = name;
            meta.Content = value;
            Page.Header.Controls.Add(meta);
        }

        public HtmlMeta CreateMetaTag(string name, string httpequiv, string value)
        {
            HtmlMeta meta = new HtmlMeta();
            meta.HttpEquiv = httpequiv;
            meta.Name = name;
            meta.Content = value;
            return meta;
        }

        private void SetRobots(Robots[] robots, bool googlebot)
        {
            List<string> value = new List<string>();

            foreach (Robots rbt in robots)
            {
                switch (rbt)
                {
                    case Robots.None: value.Add("none"); break;
                    case Robots.Follow: value.Add("follow"); break;
                    case Robots.Index: value.Add("index"); break;
                    case Robots.NoArchive: value.Add("noarchive"); break;
                    case Robots.NoFollow: value.Add("nofollow"); break;
                    case Robots.NoIndex: value.Add("noindex"); break;
                }
            }

            if (value.Count > 0)
            {
                string content = string.Empty;

                foreach (string s in value)
                {
                    if (content != string.Empty) { content += ","; }
                    content += s;
                }

                if (googlebot)
                {
                    CreateMeta("googlebot", string.Empty, content);
                }
                else
                {
                    CreateMeta("robots", string.Empty, content);
                }
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            SetPageTitle();
            if (this.ShowShortcutIcon)
            {
                Page.Header.Controls.Add(new LiteralControl("<link rel=\"icon\" href=\"/favicon.ico\" type=\"image/ico\" />"));
                Page.Header.Controls.Add(new LiteralControl("<link rel=\"shortcut icon\" href=\"/favicon.ico\"  type=\"image/ico\" />"));
            }
        }

        public T FindControl<T>(string id, bool Recursive) where T : Control
        {
            if (Recursive)
            {
                return ((T)FindControlRecursive<T>(id, this));
            }

            return ((T)base.FindControl(id));
        }

        public T FindControl<T>(string id, Control parent) where T : Control
        {
            return ((T)FindControlRecursive<T>(id, this));
        }

        public T FindControlRecursive<T>(string id, Control parent) where T : Control
        {
            if (string.Compare(parent.ID, id, true) == 0) { return ((T)parent); }

            foreach (Control child in parent.Controls)
            {
                T match = FindControlRecursive<T>(id, child);
                if (match != null) { return match; }
            }

            return null;
        }

        public void MessageBox(string message)
        {
            ClientScript.RegisterStartupScript(this.GetType(), "MessageBox", string.Format("alert('{0}');", message.Replace("'", @"\'")), true);
        }


        public void Reload()
        {
            Response.Redirect(this.Request.Url.ToString());
        }

        protected virtual void SetPageTitle()
        {
            if (this.AutoSetPageTitle && (string.IsNullOrEmpty(this.Title) || string.Compare(this.Title, "Untitled Page", true) == 0))
            {
                if (SiteMap.Enabled)
                {
                    try
                    {
                        SiteMapNode current = null;

                        if (string.IsNullOrEmpty(this.SiteMapProvider))
                        { current = SiteMap.CurrentNode; }
                        else
                        { current = SiteMap.Providers[this.SiteMapProvider].CurrentNode; }

                        if (current != null)
                        {
                            SetPageTitle(current);
                            return;
                        }
                    }
                    catch
                    {
                    }
                }

                this.Title = Path.GetFileNameWithoutExtension(Request.PhysicalPath);
            }
        }

        protected virtual void SetPageTitle(SiteMapNode current)
        {

            if (this.AutoSetPageTitle)
            {
                StringBuilder titleBuilder = new StringBuilder(200);
                titleBuilder.Append(current.Title);
                current = current.ParentNode;

                if (current != null)
                {
                    string parentPathReverse = current.Title;

                    while (current.ParentNode != null)
                    {
                        current = current.ParentNode;
                        parentPathReverse = string.Concat(current.Title, this.SiteMapNodeSeparator, parentPathReverse);
                    }
                    titleBuilder.Append(" (").Append(parentPathReverse).Append(")");
                }

                this.Title = titleBuilder.ToString();
            }
        }

        public void LoadUserControl(string path, string id, PlaceHolder container)
        {
            container.Controls.Add(LoadUserControl(path, id));
        }

        public Control LoadUserControl(string path, string id)
        {
            Control control = Page.LoadControl(path);

            if (control.GetType() == typeof(PartialCachingControl))
            {
                ((PartialCachingControl)control).ID = id;
                return ((PartialCachingControl)control);
            }

            if (control.GetType() == typeof(UserControl))
            {
                ((UserControl)control).ID = id;
                return ((UserControl)control);
            }

            return control;
        }

        public string GetPageHtml()
        {
            StringWriter sw = new StringWriter();
            HtmlTextWriter tw = new HtmlTextWriter(sw);
            this.Render(tw);
            return sw.ToString();
        }
    }

    public enum CacheControl { Public, Private, NoCache, NoStore }
    public enum Robots { None, NoIndex, Index, NoFollow, Follow, NoArchive }
    public enum UACompatible { IE5, IE7, EmulateIE7, EmulateIE8, IE8, Edge }
}
